/* greetings.c -- greetings program
 *
 * Send a message from all processes with rank != 0 to process 0.
 *    Process 0 prints the messages received.
 *
 * Input: none.
 * Output: contents of messages received by process 0.
 *
 * See Chapter 3, pp. 41 & ff in PPMPI.
 */
#include <stdio.h>
#include <string.h>
#include "mpi.h"
#include "GHood.h"

main(int argc, char* argv[]) {
    int         my_rank;       /* rank of process      */
    int         p;             /* number of processes  */
    int         source;        /* rank of sender       */
    int         dest;          /* rank of receiver     */
    int         tag = 0;       /* tag for messages     */
    char        message[500];  /* storage for message  */
    MPI_Status  status;        /* return status for    */
                               /* receive              */
  /* 
   Input Files: For PCluster  
   */
    char RAWFILE[FILENAME_MAX]="/home/jaalab/subayes/parallelRcluster/Input/LG7Simulate.txt";
    char OUTFILE[FILENAME_MAX]="/home/jaalab/subayes/parallelRcluster/Output/output.dat";
    char DATAFILE[FILENAME_MAX]="/home/jaalab/subayes/parallelRcluster/Output/JUNK.dat";
    char LOGFILE[FILENAME_MAX]="/home/jaalab/subayes/parallelRcluster/Output/LOG.dat";
    
    FILE *outfile;
    
    int order[31] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
    int loci = 31;
    
    int height = 3;
    struct GeneticData *gData;
  
  /* 
   Annealing Parameters: Job: 1: 
     Each set will have 10 replications
     Whlole Range:
     
     T-->10.0,20.0
     F-->0.25,0.5,0.75
     M-->100,200,300
     S-->0.2M,0.4M
     
     set 1:   T = 10.0, F = 0.25, M = 100, S = 0.2M
     set 2:   T = 10.0, F = 0.25, M = 100, S = 0.4M
     set 3:   T = 10.0, F = 0.25, M = 200, S = 0.2M
     
   */
    message[0]='\0';
   
    double T[3] = {10.0,10.0,10.0};
    double F[3] = {0.25,0.25,0.25};
    int M[3] = {50,100,200};
    int S[3] = {10,40,40};
    
    if(( gData = (struct GeneticData *) malloc(sizeof(struct GeneticData))) == NULL){
      printf("Insufficient memory for allocating structure ... \n");
      exit(EXIT_FAILURE);
    }
    
    outfile = fopen(OUTFILE,"w");
    
    /* Start up MPI */
    MPI_Init(&argc, &argv);

    /* Find out process rank  */
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

    /* Find out number of processes */
    MPI_Comm_size(MPI_COMM_WORLD, &p);

    if (my_rank != 0) {
    
        /* Re-seeding the peudo-random sequencer to choose a different start for different processors */
        srand(my_rank+10);
        transFormOrder(order,loci);
        
        /* Creating Genetic Data for the random order */
        getGeneticData(gData,RAWFILE,DATAFILE,LOGFILE,order,loci,height);
        
        
        
        if( my_rank >= 1 && my_rank <= 10){
           /* allocating set 1 */
           runSAParallel(gData,message,my_rank,T[0],F[0],M[0],S[0]);
        }
        if( my_rank >= 11 && my_rank <= 20){
           /* allocating set 2 */
           runSAParallel(gData,message,my_rank,T[1],F[1],M[1],S[1]);
        }
        if( my_rank >= 21 && my_rank <= 30){
           /* allocating set 3 */
           runSAParallel(gData,message,my_rank,T[2],F[2],M[2],S[2]);
        }
        
        
        
        dest = 0;
        /* Use strlen+1 so that '\0' gets transmitted */
        MPI_Send(message, strlen(message)+1, MPI_CHAR, 
            dest, tag, MPI_COMM_WORLD);
            
            
    } else { /* my_rank == 0 */
        for (source = 1; source < p; source++) {
            MPI_Recv(message, 500, MPI_CHAR, source, tag, 
                MPI_COMM_WORLD, &status);
            fprintf(outfile,"%s\n", message);
            fprintf(stdout,"%s\n", message);
        }
    }
    
    /* close outfile */
    fclose(outfile);
    /* Shut down MPI */
    MPI_Finalize();
} /* main */
